package ru.picman;

import java.util.ArrayList;
import java.util.List;

import ru.picman.util.GreenThread;

/**
 * The Egg class actually is an item. Therefore, the entity type will 
 * automatically be set to ITEM. You can take an egg by calling the
 * method {@link #take()}. If you do so, any action attached to that
 * egg will be executed. There are some default action defined (1 atm)
 * and one of these will be chosen randomly when the egg is constructed.
 * 
 * @author Matthijs
 */
public class Egg
             extends Entity
{
	/**
	 * Constructs a new Egg. See the documentation on {@link Egg this class}
	 * for further information.
	 * 
	 * @param type The type of the egg
	 * @param world The world the egg is in
	 */
	public Egg(int type, World world) {
		super(EntityType.ITEM);
		if (type < 0 || type > EGG_GOLD)
			throw new IllegalArgumentException("Invalid block type");
		this.imageID = eggs[type];
		this.type = type;
		
		setWorld(world);
		if (type == EGG_GOLD)
			setRandomAction();
		initializeActions(this);
	}
	
	/**
	 * Returns the egg type.
	 * 
	 * @return The egg type
	 */
	public int getEggType() {
		return type;
	}
	
	/**
	 * Returns the image id of the egg. The image id refers to
	 * the image which visually represents the egg.
	 * 
	 * @return the image id
	 */
	public int getImageID() {
		return imageID;
	}
	
	/**
	 * Takes the Egg. If the egg is taken the action (if any) will 
	 * be executed and the next world-tick it will be removed from
	 * the world, which usually is 'instantly'.
	 */
	public void take() {
		if (taken)
			throw new IllegalStateException("Already taken");
		taken = true;
		if (action != null)
			action.exec();
	}
	
	/**
	 * Checks if the egg is taken.
	 * 
	 * @return true, if {@link #take()} has been called earlier
	 */
	public boolean isTaken() {
		return taken;
	}
	
	/**
	 * Sets the action of this egg to the specified action.
	 * 
	 * @param action The action
	 */
	public void setAction(Action action) {
		this.action = action;
	}
	
	/**
	 * Returns the action set for this egg.
	 * 
	 * @return The action
	 */
	public Action getAction() {
		return action;
	}
	
	//
	
	/**
	 * Sets a random action for this Egg. The random action is chosen
	 * randomly from all pre-defined actions in this class.
	 */
	private void setRandomAction() {
		setAction(ACTION_FREEZE);
	}
	
	/**
	 * The default actions are initialized here. The current actions:<br/ >
	 * <br />
	 * <table>
	 * <tr>
	 * <td><b>ACTION_FREEZE</b></td><td>The pigs cannot do anything for 8 seconds</td>
	 * <tr>
	 * </table>
	 * 
	 * @param egg The instance of the egg the action is
	 */
	private static void initializeActions(final Egg egg) {
		ACTION_FREEZE = new Action() {
			public void exec() {
				final List<Pig> pigs = new ArrayList<Pig>();
				for (Entity e : egg.getWorld().getEntities())
					if (e.getType() == EntityType.PIG)
						pigs.add((Pig)e);
				for (Pig pig : pigs)
					pig.setFrozen(true);
				
				egg.getWorld().getGame().getGameLoop().addThread(new GreenThread() {
					boolean first = true;
					public void run() {
						sleep(8000);
						if (!(first ^= true))
							return;
						for (Pig pig : pigs)
							pig.setFrozen(false); 
						stop();
					}
				});
			}
		};
	}
	
	//
	
	private Action             action;
	
	private int                imageID;
	private boolean            taken;
	
	private final int          type;
	
	public static final int    EGG_WHITE = 0;
	public static final int    EGG_GOLD  = 1;
	
	public static Action       ACTION_FREEZE;
	
	private static final int[] eggs;
	
	static {
		eggs = new int[3];
		eggs[EGG_WHITE] = R.drawable.whiteegg;
		eggs[EGG_GOLD] = R.drawable.goldenegg;
	}
}
